package spring.ai_chat.Web;

import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;
import org.springframework.web.socket.client.WebSocketClient;
import org.springframework.web.socket.client.WebSocketConnectionManager;
import org.springframework.web.socket.client.standard.StandardWebSocketClient;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import spring.ai_chat.Web.pojo.MsgInfo;
import spring.ai_chat.Web.pojo.Response;
import spring.ai_chat.ollama.chatApi.OllamaChat;

import javax.net.ssl.*;
import java.security.cert.X509Certificate;
import java.io.IOException;
import java.util.Map;

@Slf4j
@Component
public class OllamaWebSocketClient extends TextWebSocketHandler {

    @Autowired
    OllamaChat mesSendServer;

    private static final ObjectMapper mapper = new ObjectMapper();
    private WebSocketConnectionManager connectionManager;
    WebSocketSession session;

    //    String websocketUrl = "wss://127.0.0.1:8080/WebSocketMessage?userId=0";
    @Value("${chat.websocketUrl}")
    String websocketUrl;

    @Autowired
    private ObjectMapper objectMapper;

    static {
        try {
            TrustManager[] trustAllCerts = new TrustManager[] {
                    new X509TrustManager() {
                        public X509Certificate[] getAcceptedIssuers() { return null; }
                        public void checkClientTrusted(X509Certificate[] certs, String authType) { }
                        public void checkServerTrusted(X509Certificate[] certs, String authType) { }
                    }
            };
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
            HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @PostConstruct
    public void connect() {
        try {

            WebSocketClient client = new StandardWebSocketClient();

            connectionManager = new WebSocketConnectionManager(client, this, websocketUrl);

            // 设置自动重连
            connectionManager.setAutoStartup(true);

            // 设置连接属性，这些可以在连接成功后读取到
            connectionManager.setAutoStartup(true);

            connectionManager.start();

            System.out.println("正在连接到WebSocket服务器: " + websocketUrl);

        } catch (Exception e) {
            System.err.println("连接WebSocket服务器失败: " + e.getMessage());
            // 可以在这里添加重试逻辑
        }
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) {
        this.session = session;
        log.info("Connected to server sessionId: {}", session.getId());

        try {
            //这里大哥招呼 让他知道你的WebSocketSession
            SomeBodyHello someBodyHello = new SomeBodyHello();

            String json = JSONUtil.toJsonStr(someBodyHello);

            TextMessage textMessage = new TextMessage(json);

            log.info("say hello {}", textMessage.getPayload());

            session.sendMessage(textMessage);

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) {
        //收到响应
        log.info("Received: {}", message.getPayload());
        try {
            Response msg1 = mapper.readValue(message.getPayload(), Response.class);

            Map<String, String> m = msg1.getData();

            MsgInfo msg =  mapToMsgInfo(m);

            //这时某人发的不用管
            if (msg.getId() == 0) {
                return;
            }

            String retMsg = mesSendServer.getResponse(msg.getUserId(), msg.getContent());

            msg.setContent(retMsg);
            msg.setUserId(0);
            msg.setUserName("某人");

            Thread.sleep(100);

            //放回回复
            session.sendMessage(new TextMessage(mapper.writeValueAsString(msg)));

            log.info("成功返回信息 {}", msg);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException(e);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Received: {","data":{"id":862,"type":"message","sessionId":87,"userId":3,"userName":"hadage","content":"qqq"}}
     */
    private MsgInfo mapToMsgInfo(Map<String, String> m) {
        return new MsgInfo(Integer.parseInt(m.get("id")), m.get("type") , Integer.parseInt(m.get("sessionId")),
                Integer.parseInt(m.get("userId")), m.get("userName"), m.get("content"));
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) {
        System.err.println("连接发生异常: " + exception.getMessage());
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) {
        System.out.println("连接关闭: " + closeStatus);
    }

    @Override
    public boolean supportsPartialMessages() {
        return false;
    }


}